This page is designed to keep track of our first golf membership at Thornbury Golf Course.
Last round inputted: 2022-04-03.
There are two courses at Thornbury, one full and one par 3. They are separated here. Scores over time are tracked to see if scores are improving (or not!).
| Ben | Doug | Lew |
|---|---|---|
| 73 | 73 | 80 |
| 107 | 103 | 113 |
| 101 | 108 | 101 |
#Par 3 course
ggplot(data = fullscores$PAR3scores[!is.na(fullscores$PAR3scores$Score),], aes(x = Date, y = Score, group = Player)) +
geom_line(aes(color = Player), size = 1.7) + geom_point(aes(shape = NULL)) + labs(title = "Total Scores for every (short course) round played so far") + scale_x_date(date_breaks = "1 week", date_labels = "%d %b") + theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust=1)) + transition_reveal(Date)
#Summary of Round totals for each player
SumTable<- sapply(unique(fullscores$fullscoresFULL$Player), function(x) summary(subset(fullscores$fullscoresFULL[!is.na(fullscores$fullscoresFULL$Score), "Score"], subset = fullscores$fullscoresFULL$Player == x)), USE.NAMES = T)
rownames(SumTable)<- c("Best", "1st Quartile", "Median", "Average", "3rd Quartile", "Worst")
SumTable %>% kableExtra::kbl(caption = "Summary of our rounds as members (full course)", align = "c", escape = FALSE, digits = 0) %>% kableExtra::kable_classic(full_width = T, html_font = "Cambria")
| Ben | Doug | Lew | |
|---|---|---|---|
| Best | 73 | 73 | 80 |
| 1st Quartile | 106 | 104 | 111 |
| Median | 108 | 108 | 114 |
| Average | 109 | 106 | 112 |
| 3rd Quartile | 115 | 111 | 117 |
| Worst | 124 | 115 | 127 |
#Summary of Round totals for each player (par 3)
SumTable<- sapply(unique(fullscores$PAR3scores$Player), function(x) summary(subset(fullscores$PAR3scores[!is.na(fullscores$PAR3scores$Score), "Score"], subset = fullscores$PAR3scores$Player == x)), USE.NAMES = T)
rownames(SumTable)<- c("Best", "1st Quartile", "Median", "Average", "3rd Quartile", "Worst")
SumTable %>% kableExtra::kbl(caption = "Summary of our rounds as members (Par 3 course)", align = "c", escape = FALSE, digits = 0) %>% kableExtra::kable_classic(full_width = T, html_font = "Cambria")
| Ben | Doug | Lew | |
|---|---|---|---|
| Best | 75 | 68 | 75 |
| 1st Quartile | 83 | 72 | 75 |
| Median | 86 | 72 | 76 |
| Average | 85 | 74 | 76 |
| 3rd Quartile | 89 | 76 | 77 |
| Worst | 93 | 79 | 79 |
Breaking the magic 100 is a intimidating mountain to climb. Doug managed it first at Thornbury on 20/09/21. So far, since we became members on 31/07/2021, there have been a total of 5 sub hundy rounds. Here is the roll of honour:
fullscores$fullscoresFULL[which(fullscores$fullscoresFULL$Score < 100),] %>% kableExtra::kbl(caption = "Sub-Hundy Roll of Honour", align = "c", escape = FALSE, digits = 0, row.names = FALSE) %>% kableExtra::kable_classic(full_width = T, html_font = "Cambria") %>% row_spec(1:nrow(fullscores$fullscoresFULL[which(fullscores$fullscoresFULL$Score < 100),]), bold = T, background = "#c9b037")
| Score | Player | Date |
|---|---|---|
| 73 | Ben | 2022-03-12 |
| 97 | Doug | 2021-09-20 |
| 99 | Doug | 2021-10-09 |
| 73 | Doug | 2022-03-12 |
| 80 | Lew | 2022-03-12 |
We want to make sure we use our memberships to the absolute max so it's worth tracking how many rounds we've played.
#+1 par3 round that we lost the scorecard for!
RoundSummary<- rbind(Full = sapply(unique(holescoresFULL$Player), function(x) holescoresFULL %>% filter(Player == x) %>% filter(!duplicated(Date)) %>% na.omit() %>% nrow(), USE.NAMES = T)+1, Par3 = sapply(unique(holescoresPAR3$Player), function(x) holescoresPAR3 %>% filter(Player == x) %>% filter(!duplicated(Date)) %>% na.omit() %>% nrow(), USE.NAMES = T)+1, TotalHoles = sapply(unique(holescoresFULL$Player), function(x) holescoresFULL %>% filter(Player == x) %>% na.omit() %>% nrow(), USE.NAMES = T), MoneySaved = sapply(unique(holescoresFULL$Player), function(x) holescoresFULL %>% filter(Player == x) %>% na.omit() %>% nrow(), USE.NAMES = T)*(34/18) + sapply(unique(holescoresPAR3$Player), function(x) holescoresPAR3 %>% filter(Player == x) %>% na.omit() %>% nrow(), USE.NAMES = T)*(15/18))
RoundSummary %>% kableExtra::kbl(caption = "Times played as members", align = "c", escape = FALSE, digits = 0) %>% kableExtra::kable_classic(full_width = T, html_font = "Cambria")
| Ben | Doug | Lew | |
|---|---|---|---|
| Full | 27 | 30 | 27 |
| Par3 | 7 | 7 | 5 |
| TotalHoles | 423 | 468 | 423 |
| MoneySaved | 889 | 974 | 859 |
NOTE: The count for the full course includes rounds when 9 holes have been played as well as a full round. One Par3 scorecard was lost to the ether so the scores are not included but that round is still represented in the times played table. Another time on the full course we didn't bother scoring because of the major puddles on the course.
The formula used for working out how much our golf would have cost uses the full price of a round on the full course (£34) and the Par 3 course (£15) and therefore doesn't take into account discount rates at certain times.
\(Cost of one hole = Full price / 18\)
\(Cost of one hole * number of holes played\)
These box plots show how each player makes it through a round. The black dots are the actual scores and the boxes show the average (blue line through box) and upper/lower quartiles (top/bottom of the box) scores for each hole. From this you may be able to spot your bogey holes (pun intended) or your best scoring holes.
Some numbers to complement these plots:
#get favourite holes by determining best average score (par adjusted?) for each player. maybe do most consistent holes too.
HoleStats<- lapply(unique(Course$`Thornbury Long`$Player), function(x) Course$`Thornbury Long` %>% filter(Player == x) %>% na.omit()) #separate by course + player and get rid of NA rounds
names(HoleStats)<- unique(Course$`Thornbury Long`$Player) #pull names across
HoleStatsAdjScore<- lapply(names(HoleStats), function(y) lapply(1:18, function(x) summary(HoleStats[[y]]["Adj_Score"][which(HoleStats[[y]][["Hole"]] == x),]))) #go by adjusted scores for summary stats
names(HoleStatsAdjScore)<- names(HoleStats) #pull names across
HoleStatsAdjScoreSummary<- lapply(HoleStatsAdjScore, unlist) #convert to dataframe for nice table. First unlist then alter dimensions
dim(HoleStatsAdjScoreSummary$Ben)<- c(6,18)
dim(HoleStatsAdjScoreSummary$Doug)<- c(6,18)
dim(HoleStatsAdjScoreSummary$Lew)<- c(6,18)
HoleStatsAdjScoreSummary<- lapply(names(HoleStatsAdjScoreSummary), function(x) t(HoleStatsAdjScoreSummary[[x]][c(1,3,4,6),])) #retain only min, median, mean, max columns
names(HoleStatsAdjScoreSummary)<- names(HoleStats)
HoleStatsAdjScoreSummary<- cbind(HoleStatsAdjScoreSummary$Ben, HoleStatsAdjScoreSummary$Doug, HoleStatsAdjScoreSummary$Lew) #bring all summary player data together
rownames(HoleStatsAdjScoreSummary)<- 1:18 #rename rownames for hole numbers
HoleStatsAdjScoreSummary<- floor(HoleStatsAdjScoreSummary) #convert to integers to make conversion to par etc much easier
HoleStatsAdjScoreSummary[HoleStatsAdjScoreSummary == -2] <- "eagle"
HoleStatsAdjScoreSummary[HoleStatsAdjScoreSummary == -1] <- "birdie"
HoleStatsAdjScoreSummary[HoleStatsAdjScoreSummary == 0] <- "par"
HoleStatsAdjScoreSummary[HoleStatsAdjScoreSummary == 1] <- "bogey"
HoleStatsAdjScoreSummary[HoleStatsAdjScoreSummary == 2] <- "double bogey"
HoleStatsAdjScoreSummary[HoleStatsAdjScoreSummary == 3] <- "triple bogey"
HoleStatsAdjScoreSummary[HoleStatsAdjScoreSummary == 4] <- "quad bogey"
for(col in 1:ncol(HoleStatsAdjScoreSummary)){
HoleStatsAdjScoreSummary[,col] <- ifelse(
HoleStatsAdjScoreSummary[,col] == "birdie",
cell_spec(HoleStatsAdjScoreSummary[,col], color = "green", bold = T),
ifelse(HoleStatsAdjScoreSummary[,col] == "par",
cell_spec(HoleStatsAdjScoreSummary[,col], color = "yellow", bold = T),
cell_spec(HoleStatsAdjScoreSummary[,col], color = "black")
))
}
HoleStatsAdjScoreSummary %>% kableExtra::kbl(caption = "Summary by Individual Hole (full course only)", align = "c", escape = FALSE, digits = 0, col.names = rep(c("Best", "Median", "Average", "Worst"), 3), row.names = T) %>% kableExtra::kable_classic(full_width = T, html_font = "Cambria", lightable_options = "striped") %>% kableExtra::add_header_above(header = c("", "Ben" = 4, "Doug" = 4, "Lew" = 4), border_left = TRUE, border_right = TRUE, line = TRUE) %>% column_spec(column = 5:8, background = "slategray1")
|
Ben
|
Doug
|
Lew
|
||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Best | Median | Average | Worst | Best | Median | Average | Worst | Best | Median | Average | Worst | |
| 1 | par | double bogey | double bogey | 5 | birdie | triple bogey | double bogey | 5 | bogey | triple bogey | triple bogey | 5 |
| 2 | par | double bogey | double bogey | 5 | birdie | bogey | bogey | triple bogey | par | double bogey | bogey | quad bogey |
| 3 | par | triple bogey | double bogey | 6 | par | double bogey | double bogey | 5 | par | double bogey | double bogey | 5 |
| 4 | par | double bogey | double bogey | quad bogey | par | double bogey | double bogey | 6 | par | double bogey | double bogey | 6 |
| 5 | par | double bogey | double bogey | 6 | par | double bogey | double bogey | 6 | bogey | double bogey | double bogey | 5 |
| 6 | birdie | bogey | bogey | 7 | par | bogey | bogey | 5 | birdie | double bogey | bogey | 5 |
| 7 | par | double bogey | double bogey | 6 | par | double bogey | bogey | quad bogey | par | double bogey | double bogey | 5 |
| 8 | par | double bogey | double bogey | 5 | par | double bogey | double bogey | 5 | bogey | triple bogey | double bogey | 6 |
| 9 | bogey | double bogey | double bogey | 6 | bogey | double bogey | double bogey | 6 | bogey | double bogey | double bogey | quad bogey |
| 10 | bogey | triple bogey | triple bogey | 6 | bogey | double bogey | double bogey | 5 | par | triple bogey | double bogey | 6 |
| 11 | par | bogey | bogey | triple bogey | par | bogey | bogey | triple bogey | par | bogey | bogey | quad bogey |
| 12 | par | bogey | bogey | quad bogey | par | bogey | bogey | quad bogey | birdie | bogey | bogey | quad bogey |
| 13 | bogey | double bogey | double bogey | quad bogey | bogey | double bogey | double bogey | quad bogey | par | double bogey | double bogey | 6 |
| 14 | par | bogey | bogey | triple bogey | par | bogey | bogey | quad bogey | par | bogey | bogey | 6 |
| 15 | bogey | triple bogey | double bogey | 5 | bogey | double bogey | double bogey | quad bogey | par | double bogey | double bogey | 5 |
| 16 | par | bogey | bogey | 5 | par | double bogey | bogey | 5 | par | double bogey | bogey | 5 |
| 17 | bogey | double bogey | double bogey | 6 | bogey | triple bogey | double bogey | 6 | par | triple bogey | triple bogey | 6 |
| 18 | par | double bogey | double bogey | 5 | par | triple bogey | double bogey | 5 | bogey | triple bogey | triple bogey | 5 |
HoleStatsAdjSD<- lapply(names(HoleStats), function(y) lapply(1:18, function(x) sd(HoleStats[[y]]["Score"][which(HoleStats[[y]][["Hole"]] == x),])))
HoleStatsAdjSD<- lapply(HoleStatsAdjSD, unlist)
names(HoleStatsAdjSD)<- names(HoleStats)
MostConsistent<- lapply(HoleStatsAdjSD, function(x) which(x == min(x)))
LeastConsistent<- lapply(HoleStatsAdjSD, function(x) which(x == max(x)))
Consistency is imperative to a good golf score. Holes that you consistently get the same score on are good markers. However, the consistency may be bad! The most consistent hole(s) for Ben is 14 where he averages bogey but the least consistent is 6 where he averages bogey. The most consistent hole(s) for Doug is 11 where he averages bogey but the least consistent is 1 where he averages double bogey. The most consistent hole(s) for Lew is 2 where he averages bogey but the least consistent is 13 where he averages double bogey.
#get favourite holes by determining best average score (par adjusted?) for each player. maybe do most consistent holes too.
HoleStats<- lapply(unique(Course$`Thornbury Long`$Player), function(x) Course$`Thornbury Short` %>% filter(Player == x) %>% na.omit()) #separate by course + player and get rid of NA rounds
names(HoleStats)<- unique(Course$`Thornbury Long`$Player) #pull names across
HoleStatsAdjScore<- lapply(names(HoleStats), function(y) lapply(1:18, function(x) summary(HoleStats[[y]]["Adj_Score"][which(HoleStats[[y]][["Hole"]] == x),]))) #go by adjusted scores for summary stats
names(HoleStatsAdjScore)<- names(HoleStats) #pull names across
HoleStatsAdjScoreSummary<- lapply(HoleStatsAdjScore, unlist) #convert to dataframe for nice table. First unlist then alter dimensions
dim(HoleStatsAdjScoreSummary$Ben)<- c(6,18)
dim(HoleStatsAdjScoreSummary$Doug)<- c(6,18)
dim(HoleStatsAdjScoreSummary$Lew)<- c(6,18)
HoleStatsAdjScoreSummary<- lapply(names(HoleStatsAdjScoreSummary), function(x) t(HoleStatsAdjScoreSummary[[x]][c(1,3,4,6),])) #retain only min, median, mean, max columns
names(HoleStatsAdjScoreSummary)<- names(HoleStats)
HoleStatsAdjScoreSummary<- cbind(HoleStatsAdjScoreSummary$Ben, HoleStatsAdjScoreSummary$Doug, HoleStatsAdjScoreSummary$Lew) #bring all summary player data together
rownames(HoleStatsAdjScoreSummary)<- 1:18 #rename rownames for hole numbers
HoleStatsAdjScoreSummary<- floor(HoleStatsAdjScoreSummary) #convert to integers to make conversion to par etc much easier
HoleStatsAdjScoreSummary[HoleStatsAdjScoreSummary == -2] <- "eagle"
HoleStatsAdjScoreSummary[HoleStatsAdjScoreSummary == -1] <- "birdie"
HoleStatsAdjScoreSummary[HoleStatsAdjScoreSummary == 0] <- "par"
HoleStatsAdjScoreSummary[HoleStatsAdjScoreSummary == 1] <- "bogey"
HoleStatsAdjScoreSummary[HoleStatsAdjScoreSummary == 2] <- "double bogey"
HoleStatsAdjScoreSummary[HoleStatsAdjScoreSummary == 3] <- "triple bogey"
HoleStatsAdjScoreSummary[HoleStatsAdjScoreSummary == 4] <- "quad bogey"
for(col in 1:ncol(HoleStatsAdjScoreSummary)){
HoleStatsAdjScoreSummary[,col] <- ifelse(
HoleStatsAdjScoreSummary[,col] == "birdie",
cell_spec(HoleStatsAdjScoreSummary[,col], color = "green", bold = T),
ifelse(HoleStatsAdjScoreSummary[,col] == "par",
cell_spec(HoleStatsAdjScoreSummary[,col], color = "yellow", bold = T),
cell_spec(HoleStatsAdjScoreSummary[,col], color = "black")
))
}
HoleStatsAdjScoreSummary %>% kableExtra::kbl(caption = "Summary by Individual Hole (Par 3 course only)", align = "c", escape = FALSE, digits = 0, col.names = rep(c("Best", "Median", "Average", "Worst"), 3), row.names = T) %>% kableExtra::kable_classic(full_width = T, html_font = "Cambria", lightable_options = "striped") %>% kableExtra::add_header_above(header = c("", "Ben" = 4, "Doug" = 4, "Lew" = 4), border_left = TRUE, border_right = TRUE, line = TRUE) %>% column_spec(column = 5:8, background = "slategray1")
|
Ben
|
Doug
|
Lew
|
||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Best | Median | Average | Worst | Best | Median | Average | Worst | Best | Median | Average | Worst | |
| 1 | bogey | double bogey | double bogey | triple bogey | par | double bogey | bogey | quad bogey | bogey | bogey | bogey | triple bogey |
| 2 | bogey | double bogey | double bogey | triple bogey | par | bogey | bogey | triple bogey | double bogey | double bogey | double bogey | double bogey |
| 3 | par | bogey | bogey | quad bogey | par | bogey | bogey | double bogey | bogey | bogey | bogey | bogey |
| 4 | par | bogey | bogey | quad bogey | par | bogey | bogey | double bogey | par | double bogey | bogey | triple bogey |
| 5 | bogey | double bogey | double bogey | triple bogey | par | bogey | par | bogey | bogey | bogey | bogey | bogey |
| 6 | birdie | bogey | par | double bogey | par | par | par | double bogey | par | par | par | bogey |
| 7 | par | bogey | bogey | triple bogey | birdie | par | par | bogey | par | bogey | bogey | double bogey |
| 8 | bogey | double bogey | double bogey | 6 | bogey | bogey | bogey | triple bogey | bogey | bogey | bogey | bogey |
| 9 | double bogey | triple bogey | triple bogey | quad bogey | bogey | bogey | bogey | triple bogey | double bogey | double bogey | double bogey | triple bogey |
| 10 | par | double bogey | bogey | triple bogey | par | bogey | bogey | double bogey | bogey | bogey | double bogey | quad bogey |
| 11 | par | bogey | bogey | double bogey | par | bogey | par | double bogey | par | bogey | bogey | triple bogey |
| 12 | par | double bogey | double bogey | 6 | par | par | bogey | triple bogey | bogey | bogey | bogey | double bogey |
| 13 | par | par | par | double bogey | par | bogey | par | bogey | par | par | par | bogey |
| 14 | par | bogey | bogey | double bogey | par | bogey | bogey | triple bogey | par | bogey | bogey | triple bogey |
| 15 | bogey | double bogey | double bogey | triple bogey | par | bogey | bogey | triple bogey | par | bogey | bogey | double bogey |
| 16 | par | bogey | par | double bogey | par | bogey | par | double bogey | birdie | par | par | double bogey |
| 17 | par | bogey | bogey | 5 | par | bogey | bogey | double bogey | par | bogey | bogey | double bogey |
| 18 | birdie | double bogey | double bogey | quad bogey | eagle | bogey | par | double bogey | bogey | bogey | bogey | bogey |
HoleStatsAdjSD<- lapply(names(HoleStats), function(y) lapply(1:18, function(x) sd(HoleStats[[y]]["Score"][which(HoleStats[[y]][["Hole"]] == x),])))
HoleStatsAdjSD<- lapply(HoleStatsAdjSD, unlist)
names(HoleStatsAdjSD)<- names(HoleStats)
MostConsistent<- lapply(HoleStatsAdjSD, function(x) which(x == min(x)))
LeastConsistent<- lapply(HoleStatsAdjSD, function(x) which(x == max(x)))
I think we all consider Thornbury to be stacked with harder holes at the end of the round. So how do our scores on the front and back 9s compare?
FrontvsBack<- data.frame(na.omit(cbind(Front9 = unlist(lapply(c("Ben", "Doug", "Lew"), function(y) lapply(names(golfscores1$holescoresFULL), function(x) sum(golfscores1$holescoresFULL[[x]][["Score"]][golfscores1$holescoresFULL[[x]][["Player"]] == y & golfscores1$holescoresFULL[[x]][["Hole"]] %in% c(1:9)])))), Back9 = unlist(lapply(c("Ben", "Doug", "Lew"), function(y) lapply(names(golfscores1$holescoresFULL), function(x) sum(golfscores1$holescoresFULL[[x]][["Score"]][golfscores1$holescoresFULL[[x]][["Player"]] == y & golfscores1$holescoresFULL[[x]][["Hole"]] %in% c(10:18)])))), Player = c(rep("Ben", length(unique(golfscores1[["holescoresFULL"]]))), rep("Doug", length(unique(golfscores1[["holescoresFULL"]]))), rep("Lew", length(unique(golfscores1[["holescoresFULL"]])))), Date = as.Date(unlist(lapply(c("Ben", "Doug", "Lew"), function(y) lapply(names(golfscores1$holescoresFULL), function(x) unique(golfscores1$holescoresFULL[[x]][["Date"]][golfscores1$holescoresFULL[[x]][["Player"]] == y])))), origin = "1970-01-01"))))
#I think the na.omit converts things to character so scores need to be returned to numeric
FrontvsBack$Front9<- as.numeric(FrontvsBack$Front9)
FrontvsBack$Back9<- as.numeric(FrontvsBack$Back9)
FrontvsBackTable<- t(format(sapply(unique(FrontvsBack$Player), function(x) summary(subset(FrontvsBack$Front9, subset = FrontvsBack$Player == x)), USE.NAMES = T)[c(1,3,4,6),], digits = 2))
FrontvsBackTable<- cbind(FrontvsBackTable, t(format(sapply(unique(FrontvsBack$Player), function(x) summary(subset(FrontvsBack$Back9, subset = FrontvsBack$Player == x)), USE.NAMES = T)[c(1,3,4,6),], digits = 2)))
FrontvsBackTable %>% kableExtra::kbl(caption = "Front vs Back 9s", align = "c", escape = FALSE, digits = 0, col.names = rep(c("Best", "Median", "Average", "Worst"), 2)) %>% add_header_above(c(" ", "Front 9" = 4, "Back 9" = 4)) %>% column_spec(5, border_right = T) %>% kableExtra::kable_classic(full_width = T, html_font = "Cambria")
| Best | Median | Average | Worst | Best | Median | Average | Worst | |
|---|---|---|---|---|---|---|---|---|
| Ben | 35 | 54 | 54 | 67 | 38 | 54 | 55 | 61 |
| Doug | 36 | 53 | 52 | 58 | 37 | 54 | 54 | 60 |
| Lew | 40 | 56 | 55 | 65 | 40 | 58 | 57 | 72 |
As a group, we average 54 strokes on the front 9 and 55 strokes on the back 9. The best anyone has scored on the front 9 is 35 (the worst is 67). The best anyone has scored on the back 9 is 37 (the worst is 72).
Tweet tweet, there be birdies around. When were they spotted?
holescores[which(holescores$Adj_Score < 0), c(1,3,6,4,5)] %>% kableExtra::kbl(caption = "Twitchers", align = "c", escape = FALSE, digits = 0, row.names = FALSE) %>% kableExtra::kable_classic(full_width = T, html_font = "Cambria")
| Hole | Par | Score | Date | Player |
|---|---|---|---|---|
| 1 | 5 | 4 | 2021-07-31 | Doug |
| 18 | 3 | 1 | 2021-09-22 | Doug |
| 7 | 3 | 2 | 2021-09-29 | Doug |
| 18 | 3 | 2 | 2021-09-29 | Ben |
| 6 | 3 | 2 | 2021-10-06 | Ben |
| 16 | 3 | 2 | 2021-10-06 | Lew |
| 12 | 3 | 2 | 2021-11-14 | Lew |
| 6 | 3 | 2 | 2021-11-28 | Ben |
| 6 | 3 | 2 | 2021-12-19 | Lew |
| 2 | 3 | 2 | 2022-03-12 | Doug |
Here would be a good time to mention that the round played on the Par 3 course on 22nd September 2021 by the right honourable Douglas is an unverifiable round. Despite us all believing that he "got a hole in one" he did it when noone else was around to see it. The jury will, unfortunately, always be out on this one.
Some players may not be able to handle their wood but are deadly with an iron. To roughly gauge long vs short game, Par can be used to see how well our golfing warriors perform on different types of holes. Looking at overall performance on holes with different Par looks a little something like this:
...and as histograms:
These three noble warriors will probably be scratch golfers in no time. So this graph is designed to document their rise to the pro game.
Handicap was calculated by taking the adjusted course score (max quadruple bogey per hole) over the last few rounds then dividing it by the number of rounds included. The official maximum handicap was 28 but it's been upped to 54 now! Par 3 courses have been excluded from the handicap calculations, as have any cheeky 9 hole rounds.
This graph would probably be better with a rolling summary. i.e. for the last 5 rounds record handicap after rounds 1,2,3 then 2,3,4 then 3,4,5. It'll be a better measure of progress over time. Work backwards from the last round using lapply and a sequence. Hard to implement.
Even better would be a proper handicap calculation where the worst and best 4 holes are removed to get a more meaningful gauge of play.